//
//  KATImage.m
//  KATFramework
//
//  Created by Yi Yu on 2017/6/28.
//  Copyright © 2017年 KatApp. All rights reserved.
//

#import "KATImage.h"
#import "KATImageViewer.h"




#define IMAGE_STATUS_INIT 0
#define IMAGE_STATUS_LOADING 1
#define IMAGE_STATUS_OK 2
#define IMAGE_STATUS_FAIL 3
#define IMAGE_STATUS_ERROR 4



@interface KATImage ()

///图片的链接地址
@property(nonatomic,copy) NSString *url;

///图片的文件路径
@property(nonatomic,copy) NSString *path;

///帧数
@property(nonatomic,assign) unsigned long long frameCount;

///图片帧数组
@property(nonatomic,retain) KATArray<__kindof UIImage *> *frames;

///帧动画
@property(nonatomic,retain) CAAnimation *frameAnimation;

///帧动画时长
@property(nonatomic,assign) double frameAnimationDuration;

///点击手势
@property(nonatomic,retain) UITapGestureRecognizer *singleTap;

///图片资源
@property(nonatomic,retain) UIImage *source;

///状态
@property(nonatomic,assign) int status;


@end



@implementation KATImage

///缓存目录
static NSString *_cacheDir=nil;

///占位图片
static UIImage *_holderImage=nil;

///失败图片
static UIImage *_brokenImage=nil;



#pragma -mark 类方法


//设置缓存目录
+ (void)setCacheDir:(NSString *)dir
{
    if(_cacheDir!=dir)
    {
        [_cacheDir release];
        _cacheDir=[dir retain];
        
        //创建目录
        if(![KATFileUtil existsFile:_cacheDir])
        {
            if([KATFileUtil createDir:_cacheDir])
            {
                
            }
            else
            {
                [_cacheDir release];
                _cacheDir=nil;
            }
        }
    }
}


//获取缓存目录
+ (NSString *)cacheDir
{
    return _cacheDir;
}


//设置占位图片
+ (void)setHolderImage:(UIImage *)image
{
    if(image!=_holderImage)
    {
        [_holderImage release];
        _holderImage=[image retain];
    }
}


//获取占位图片
+ (UIImage *)holderImage
{
    return _holderImage;
}


//设置失败图片
+ (void)setBrokenImage:(UIImage *)image
{
    if(image!=_brokenImage)
    {
        [_brokenImage release];
        _brokenImage=[image retain];
    }
}


//获取失败图片
+ (UIImage *)brokenImage
{
    return _brokenImage;
}


//清空缓存
+ (void)clearCache
{
    if(_cacheDir)
    {
        //删除目录
        [KATFileUtil removeFile:_cacheDir];
        
        //创建目录
        if(![KATFileUtil existsFile:_cacheDir])
        {
            if([KATFileUtil createDir:_cacheDir])
            {
                
            }
            else
            {
                [_cacheDir release];
                _cacheDir=nil;
            }
        }
    }
}


//文件名转化
+ (NSString *)fileNameWithUrl:(NSString *)url
{
    if(url)
    {
        return [[[url stringByReplacingOccurrencesOfString:@"/" withString:@"_"] stringByReplacingOccurrencesOfString:@":" withString:@"_"] stringByReplacingOccurrencesOfString:@"?" withString:@"_"];
    }
    
    return nil;
}


//获取实例
+ (instancetype)image
{
    //初始化缓存目录
    static dispatch_once_t predicate;
    
    dispatch_once(&predicate, ^
    {
        if(!_cacheDir)
        {
            [self setCacheDir:[NSString stringWithFormat:@"%@/KATWebImageCache",TEMP_PATH]];
        }
        
        if(!_holderImage)
        {
            [self setHolderImage:[[KATButton buttonWithFrame:RECT(0, 220, 256, 256) type:KATButtonTypeImage color:KCOLOR_GRAY lineWidth:4.0 scale:1.0 andOnClickAction:nil] button2Image]];
        }
        
        if(!_brokenImage)
        {
            [self setBrokenImage:[[KATButton buttonWithFrame:RECT(0, 220, 256, 256) type:KATButtonTypeBrokenImage color:KCOLOR_GRAY lineWidth:4.0 scale:1.0 andOnClickAction:nil] button2Image]];
        }
        ;
    });
    
    
    KATImage *img=[[[self alloc] init] autorelease];
        
    img.animationTimingMode=kCAMediaTimingFunctionLinear;
    
    img.isAutoPlayAnimation=YES;
    img.path=nil;
    img.url=nil;
    img.frameCount=0;
    img.frames=nil;
    img.frameAnimation=nil;
    img.frameAnimationDuration=0;
    img.isTapToShow=NO;
    img.clipsToBounds=YES;
    img.source=nil;
    img.isParsingImageAsync=NO;
    img.singleTap=[[[UITapGestureRecognizer alloc] initWithTarget:img action:@selector(_imageTap)] autorelease];
    img.singleTap.delegate=img;
    
    //添加手势
    [img addGestureRecognizer:img.singleTap];
    
    //状态
    img.status=IMAGE_STATUS_INIT;
    
    return img;
}


#pragma -mark 对象方法


- (void)setContents:(UIImage *)contents
{
    if(!contents)//置空
    {
        [self clearImage];
    }
    else
    {
        [self stop];
    }
    
    self.source=contents;
    
    [super setContents:contents];
}


//直接加载图片
- (void)loadWithImage:(UIImage *)image
{
    [self clearImage];
    
    self.contents=image;
    
    _status=IMAGE_STATUS_OK;
}


//通过文件路径加载图片
- (void)loadWithPath:(NSString *)path
{
    _status=IMAGE_STATUS_LOADING;
    
    self.path=path;
    
    //设置
    [self _setImage];

}


//通过URL加载图片，先考虑缓存中的图片，且下载的图片会保存在缓存中
- (void)loadWithURL:(NSString *)url
{
    [self loadWithURL:url andCompletion:nil];
}


//通过URL加载图片，先考虑缓存中的图片，且下载的图片会保存在缓存中，图片下载设置完成后回调
- (void)loadWithURL:(NSString *)url andCompletion:(void (^)(BOOL success))completion
{
    _status=IMAGE_STATUS_LOADING;
    
    if(_holderImg)
    {
        self.contents=_holderImg;
    }
    else if(_holderImage)
    {
        self.contents=_holderImage;
    }
    
    self.url=url;
    
    NSString *path=[NSString stringWithFormat:@"%@/%@",_cacheDir,[KATImage fileNameWithUrl:url]];
    
    if([KATFileUtil existsFile:path])//缓存中有
    {
        self.path=path;
        
        //设置
        [self _setImage];
        
        if(completion)
        {
            completion(YES);
        }
    }
    else//网络下载
    {
        //下载
        [[KATHttpRequest request] downloadFile:path withUrl:url replaceable:NO append:NO andCallback:^(BOOL success)
        {
            if(![url isEqualToString:_url])//URL地址发生改变
            {
                return;
            }
            
            if(success)//下载成功
            {
                self.path=path;
                
                //设置
                [self _setImage];
                
                if(completion)
                {
                    completion(YES);
                }
            }
            else//下载失败
            {
                _status=IMAGE_STATUS_FAIL;
                
                self.path=nil;
                
                //设置失败图片
                if(_brokenImg)
                {
                    self.contents=_brokenImg;
                }
                else if(_brokenImage)
                {
                    self.contents=_brokenImage;
                }
                
                if(completion)
                {
                    completion(NO);
                }
            }
        }];
    }
}


//重新加载
- (void)reload
{
    if(_path)//先通过文件路径加载
    {
        [self loadWithPath:_path];
    }
    else if(_url)//再通过URL加载
    {
        [self loadWithURL:_url];
    }
}


//播放
- (void)play
{
    if(self.contents && _source && _frameAnimation && _frameCount>1 && self.superview)
    {
        [self clearAnimations];
        [self startAnimation:_frameAnimation andDelay:0];
    }
}


//停止播放
- (void)stop
{
    [self clearAnimations];
}


//清除图片
- (void)clearImage
{
    [self stop];
    self.frameAnimation=nil;
    self.frames=nil;
    self.frameCount=0;
    self.source=nil;
    self.path=nil;
}


//显示某一帧
- (void)displayWithFrame:(int)frame
{
    if(_frames && frame>=0 && frame<_frames.length)
    {
        [self clearAnimations];
        
        self.layer.contents=(__bridge id)((UIImage *)[_frames get:frame]).CGImage;
    }
}


//全屏显示
- (void)fullScreenShow
{
    if(self.contents)
    {
        [[KATImageViewer viewer] showWithImage:self];
    }
}


//移除点击手势
- (void)removeTapGesture
{
    [self removeGestureRecognizer:_singleTap];
}


//恢复点击手势
- (void)restoreTapGesture
{
    [self addGestureRecognizer:_singleTap];
}


#pragma -mark 内部方法

//图片点击
- (void)_imageTap
{
    if(_status==IMAGE_STATUS_FAIL || _status==IMAGE_STATUS_ERROR)//失败后重新下载
    {
        [self reload];
    }
    else if(_status==IMAGE_STATUS_OK && _isTapToShow)//加载完成
    {
        [self fullScreenShow];
    }
}


//异步解压并设置图片
- (void)_setImage
{
    if(_path)
    {
        [self stop];
        self.frameAnimation=nil;
        self.frames=nil;
        self.frameCount=0;
        self.source=nil;
        
        self.path=_path;
        
        if(_isParsingImageAsync)//异步加载解压图片
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^
            {
                //加载
                UIImage *image=[UIImage imageWithContentsOfFile:_path];
                
                if(image)
                {
                    self.source=image;
                    
                    //压缩并适配尺寸
                    image=[KATImageUtil fitImage:image withSize:image.size andScale:0];
                    
                    //显示
                    dispatch_sync(dispatch_get_main_queue(), ^
                    {
                        _status=IMAGE_STATUS_OK;
                        
                        self.contents=image;
                        
                        //解析GIF
                        [self _parseGif];
                    });
                }
                else
                {
                    _status=IMAGE_STATUS_ERROR;
                    
                    self.source=nil;
                    
                    //设置失败图片
                    if(_brokenImg)
                    {
                        self.contents=_brokenImg;
                    }
                    else if(_brokenImage)
                    {
                        self.contents=_brokenImage;
                    }
                }
            });
        }
        else//同步解析
        {
            //加载
            UIImage *image=[UIImage imageWithContentsOfFile:_path];
            
            if(image)
            {
                self.contents=image;

                _status=IMAGE_STATUS_OK;
                
                //解析GIF
                [self _parseGif];
            }
            else
            {
                _status=IMAGE_STATUS_ERROR;
                
                self.source=nil;
                
                //设置失败图片
                if(_brokenImg)
                {
                    self.contents=_brokenImg;
                }
                else if(_brokenImage)
                {
                    self.contents=_brokenImage;
                }
            }
        }
    }
    else
    {
        self.contents=nil;
    }
}



//解析Gif图片
- (void)_parseGif
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
    {        
        //获取图片资源
        CGImageSourceRef src=CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:_path], NULL);
        
        self.frameCount=CGImageSourceGetCount(src);
        
        if(_frameCount>1)//多帧
        {
            self.frames=[KATArray arrayWithCapacity:(int)_frameCount];
            self.frameAnimationDuration=0.0;
            
            NSMutableArray *values=[NSMutableArray arrayWithCapacity:(NSUInteger)_frameCount];//动画值数组
            NSMutableArray *times=[NSMutableArray arrayWithCapacity:(NSUInteger)_frameCount];//动画时间数组
            NSMutableArray *delays=[NSMutableArray arrayWithCapacity:(NSUInteger)_frameCount];//每帧延迟时间
            
            float repeat=-1;//重复次数
            
            //遍历
            for(unsigned long long i=0;i<_frameCount;i++)
            {
                //获取每帧
                CGImageRef frame=CGImageSourceCreateImageAtIndex(src, (size_t)i, NULL);
                UIImage *img=[UIImage imageWithCGImage:frame];
                
                [values addObject:img];
                [_frames put:img];
                
                CGImageRelease(frame);
                
                //获取每帧信息
                NSDictionary *dict=(__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(src, (size_t)i, NULL);
                
                //获取尺寸(没设置过尺寸的则自动设置尺寸)
                //                    if(self.bounds.size.width<=0 || self.bounds.size.height<=0)
                //                    {
                //                        self.bounds=CGRectMake(0, 0, [[dict valueForKey:(NSString*)kCGImagePropertyPixelWidth] floatValue]/[KATAppUtil screenScale], [[dict valueForKey:(NSString*)kCGImagePropertyPixelHeight] floatValue]/[KATAppUtil screenScale]);
                //                    }
                
                //获取每帧时长
                NSDictionary *gifDict=[dict valueForKey:(NSString *)kCGImagePropertyGIFDictionary];
                [delays addObject:[gifDict valueForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime]];
                
                //总时长
                self.frameAnimationDuration=self.frameAnimationDuration+[[gifDict valueForKey:(NSString*)kCGImagePropertyGIFUnclampedDelayTime] floatValue];
                
                //重复次数
                if(i==0)
                {
                    if([gifDict valueForKey:(NSString *)kCGImagePropertyGIFLoopCount])
                    {
                        repeat=[[gifDict valueForKey:(NSString *)kCGImagePropertyGIFLoopCount] floatValue];
                    }
                }
                
                [dict release];
            }
            
            //计算动画时长
            float time=0;
            
            for(int i=0;i<delays.count;i++)
            {
                float t=[[delays objectAtIndex:i] floatValue];
                time+=t;
                
                [times addObject:@(time/self.frameAnimationDuration)];
            }
            
            //生成动画
            dispatch_sync(dispatch_get_main_queue(), ^
            {
                self.frameAnimation=[self animationWithMode:SPRITE_MODE_CONTENTS keyValues:values keyTimes:times duration:self.frameAnimationDuration repeat:repeat autoreverses:NO delay:0];
            });
        }
        else
        {
            self.frames=nil;
            self.frameAnimationDuration=0;
            self.frameAnimation=nil;
        }
        
        if(src)
        {
            CFRelease(src);
        }
        
        
        //自动播放
        if(_isAutoPlayAnimation)
        {
            dispatch_sync(dispatch_get_main_queue(), ^
            {
                [self play];
            });
        }
    });
}



//事件同时传递给其他View
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if(_isTapToShow)
    {
        return NO;
    }
    
    return YES;
}


//图片复制(手势会失效)
- (instancetype)copyWithZone:(NSZone *)zone
{
    KATImage *img=[[[self class] allocWithZone: zone] init];
        
    img.animationTimingMode=self.animationTimingMode;
    
    img.frame=self.frame;
    img.isAutoPlayAnimation=_isAutoPlayAnimation;
    img.path=_path;
    img.url=_url;
    img.frameCount=_frameCount;
    img.frames=[_frames copy];
    img.frameAnimation=_frameAnimation;
    img.frameAnimationDuration=_frameAnimationDuration;
    img.contents=_source;
    img.source=_source;
    img.status=_status;
    
//    if(self.animating)
//    {
//        [img play];
//    }
    
    return img;
}


- (void)removeFromSuperview
{
    [self stop];
    
    [super removeFromSuperview];
}


//释放内存
- (void)dealloc
{
//    NSLog(@"KATImage is dealloc...");
    
    [self stop];
    
    [_url release];
    [_path release];
    [_frames release];
    [_frameAnimation release];
    [_singleTap release];
    [_source release];
    [_holderImg release];
    [_brokenImg release];
    
    [super dealloc];
}




@end
